//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace Microsoft.Research.DataLayer
{
    partial class Job
    {
        /// <summary>
        /// This method keeps polling the registry to
        /// check if the job has completed i.e. status
        /// of job is set to complete. If the job status
        /// is anything other than running this method
        /// returns immediately. The called should thus
        /// check the job status to be sure if the job
        /// completed successfully.
        /// </summary>
        /// <param name="waitTime">Interval in milli seconds</param>
        public void WaitForCompletion(int waitTime)
        {
            // Divide the wait time into 10 intervals
            // at which to poll the registry for querying the
            // status.
            this.Refresh();
            if (!(JobStatus.Running == this.Status || JobStatus.Initializing == this.Status
                || JobStatus.NotStarted == this.Status || JobStatus.Waiting == this.Status))
                return;
            int sleepInterval = waitTime / 10;
            for (int i = 0; i < 10; ++i)
            {
                this.Refresh();
                if (this.Status == JobStatus.Completed)
                    return;
                System.Threading.Thread.Sleep(sleepInterval);
            }
        }

        public void ExportToPackage(Connection targetConnection)
        {
            List<IObject> objects = new List<IObject>();
            objects.Add(this);
            if (null != this.scheduledby)
                objects.Add(this.scheduledby);

            // Assuming that a job only contains WF's
            foreach (ActivityInstance instance in this.ActivityInstances)
                objects.Add(instance.Activity.ActivitySequences[0]);
            ExportHelper.ExportObjects(objects, null, targetConnection);
        }


        #region CommonSearches
        public sealed class CommonSearches
        {
            private CommonSearches()
            {
            }

            /// <summary>
            ///  Retreive all the currently running jobs from the registry.
            /// </summary>
            /// <param name="connection">The registry connection.</param>
            /// <returns>Collection of all the jobs in the registry.</returns>
            public static Collection<Job> GetRunningJobs(Connection connection,  Job.ISearch.ISearchClause filter)
            {
                #region Validation of Arguments
                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }
                #endregion

                Collection<Job> jobList = null;
                try
                {
                    Job.ISearch searchQuery = Job.ISearch.Create();
                    searchQuery.Query = Job.ISearch.AND(
                        Job.ISearch.OR(
                            Job.ISearch.Status(EnumFieldBase.Condition.Equals, JobStatus.Running),
                            Job.ISearch.Status(EnumFieldBase.Condition.Equals, JobStatus.StartPending)
                        ),
                        Job.ISearch.IsDeleted(BooleanField.Condition.Equals, false));
                    if (null != filter)
                    {
                        searchQuery.Query = Job.ISearch.AND(searchQuery.Query, filter);
                    }
                    jobList = new Collection<Job>(Job.Search(searchQuery, connection));
                }
                catch (RecordNotFoundException)
                {
                }
                return jobList;
            }

            /// <summary>
            /// Retrieve the completed jobs from the registry.
            /// </summary>
            /// <param name="connection">The registry connection.</param>
            /// <returns>Collection of completed jobs.</returns>
            public static Collection<Job> GetCompletedJobs(Connection connection, Job.ISearch.ISearchClause filter)
            {
                #region Validation of Arguments
                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }
                #endregion

                Collection<Job> jobList = null;
                try
                {
                    Job.ISearch searchQuery = Job.ISearch.Create();
                    Job.ISearch.ISearchClause clause = Job.ISearch.AND(
                                                            Job.ISearch.OR(
                                                                Job.ISearch.Status(EnumFieldBase.Condition.Equals, JobStatus.Aborted),
                                                                Job.ISearch.Status(EnumFieldBase.Condition.Equals, JobStatus.Completed)
                                                            ),
                                                            Job.ISearch.IsDeleted(BooleanField.Condition.Equals, false));
                    if (null != filter)
                    {
                        searchQuery.Query = Job.ISearch.AND(clause, filter);
                    }
                    else
                    {
                        searchQuery.Query = clause;
                    }
                    jobList = new Collection<Job>(Job.Search(searchQuery, connection));
                }
                catch (RecordNotFoundException)
                {
                }
                return jobList;
            }
        }
        #endregion

    }
}
